package com.cpit.qualitycontrol.web.controller;

import com.cpit.platform.common.constant.LogConstant;
import com.cpit.platform.common.entity.Result;
import com.cpit.platform.common.entity.TableDataQueryCondition;
import com.cpit.platform.common.entity.TableJsonData;
import com.cpit.platform.common.excel.ExportExcel;
import com.cpit.platform.common.excel.ImportExcel;
import com.cpit.platform.common.exception.CodeException;
import com.cpit.platform.common.utils.ExcelImportUtils;
import com.cpit.platform.common.utils.ResultUtil;
import com.cpit.platform.dto.OperLog;
import com.cpit.platform.log.LogOperator;
import com.cpit.platform.service.OperLogService;
import com.cpit.platform.service.impl.OperLogServiceImpl;
import com.cpit.qualitycontrol.common.constant.LogConstantEx;
import com.cpit.qualitycontrol.entity.ProductLine;
import com.cpit.qualitycontrol.service.ProductLineService;
import com.cpit.qualitycontrol.service.impl.ServiceUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import com.cpit.qualitycontrol.entity.Project;
import com.cpit.qualitycontrol.service.ProjectService;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping(value = "/Project")
public class ProjectController {

    private final String loggerName = this.getClass().getName();

    @Autowired
    private ProjectService projectService = null;
    @Autowired
    private ProductLineService productLineService;
    @Autowired
    private OperLogService operLogService;
    @ApiOperation(value = "查询所有项目", notes = "无条件查询项目信息，返回对象List，项目信息中不包含组织")
    @ResponseBody
    //@PreAuthorize("hasAuthority('queryProject')")
    @RequestMapping(value = "/queryAllProject", method = RequestMethod.GET)
    public List<Project> queryAllProject() {
        return this.projectService.findAll();
    }


    @ApiOperation(value = "查询项目", notes = "通过条件查询项目信息，返回jqGrid分页JSON形式" +
            "支持分页查询，支持模糊查询。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cond", value = "JqGrid的条件对象，由JqGrid根据js参数自动封装。", required = true, dataType = "TableDataQueryContidion")
    })
    @SuppressWarnings("rawtypes")
    @ResponseBody
    //@PreAuthorize("hasAuthority('queryProject')")
    @RequestMapping(value = "/queryProjectJqg", method = RequestMethod.GET)
    public TableJsonData queryProjectJqg(TableDataQueryCondition cond) {
        TableJsonData tjd = this.projectService.findByConditionJqg(cond);
        return tjd;
    }

    @ApiOperation(value = "创建项目", notes = "用户手工指定项目并创建，" +
            "需要手动输入项目名称和描述信息，项目名称不能重复。")
    @ApiImplicitParam(name = "data", value = "项目对象", required = true, dataType = "Project")
    @ResponseBody
    //@PreAuthorize("hasAuthority('createProject')")
    @RequestMapping(value = "/createProject", method = RequestMethod.POST)
    public Result<Project> createProject(@RequestBody Project data) {
        if ( StringUtils.isEmpty(data.getName())
                || StringUtils.isEmpty(data.getProductLineId()) /**|| (StringUtils.isEmpty(data.getConstructionOrganization())&&data.getConstructionOrganization().size()!=0)*/
                ) {
            writeLog(LogConstant.OPER_CREATE,Result.CODE_FAILED,"项目信息不全");

            return ResultUtil.error(Result.CODE_FAILED, "项目信息不全，请补充！");
        }
        try {
            Project retProject = this.projectService.create(data);
            writeLog(LogConstant.OPER_CREATE,Result.CODE_SUCCESS,"项目："+retProject.getName());
            return new Result<>(Result.CODE_SUCCESS, "", retProject);
        } catch (Exception e) {
            LogOperator.err(loggerName, "createProject error", e);
            writeLog(LogConstant.OPER_CREATE,Result.CODE_FAILED,e.getMessage());
            return new Result<>(Result.CODE_FAILED, e.getMessage(), data);
        }
    }

    @ApiOperation(value = "修改项目", notes = "用户手工指定项目并修改，" +
            "需要手动输入项目名称和描述信息，项目名称不能重复。")
    @ApiImplicitParam(name = "data", value = "项目对象", required = true, dataType = "Project")
    @ResponseBody
    //@PreAuthorize("hasAuthority('modifyProject')")
    @RequestMapping(value = "/modifyProject", method = RequestMethod.POST)
    public Result<Project> modifyProject(@RequestBody Project data) {
        if (StringUtils.isEmpty(data.getName())
                || StringUtils.isEmpty(data.getProductLineId()) /**|| (StringUtils.isEmpty(data.getConstructionOrganization())&&data.getConstructionOrganization().size()!=0)*/
                ) {
            writeLog(LogConstant.OPER_MODIFY,Result.CODE_FAILED,"项目信息不全");
            return ResultUtil.error(Result.CODE_FAILED, "项目信息不全，请补充！");
        }
        try {
            Project retProject = this.projectService.modify(data);
            writeLog(LogConstant.OPER_MODIFY,Result.CODE_SUCCESS,"项目："+retProject.getName());
            return new Result<>(Result.CODE_SUCCESS, "", retProject);
        } catch (Exception e) {
            LogOperator.err(loggerName, "modifyProject error", e);
            writeLog(LogConstant.OPER_MODIFY,Result.CODE_FAILED,e.getMessage());
            return new Result<>(Result.CODE_FAILED, e.getMessage(), data);
        }
    }

    @ApiOperation(value = "删除项目", notes = "在系统中删除指定项目")
    @ApiImplicitParam(name = "data", value = "项目对象", required = true, dataType = "Project")
    @ResponseBody
    //@PreAuthorize("hasAuthority('deleteProject')")
    @RequestMapping(value = "/deleteProject", method = RequestMethod.DELETE)
    public Result<Project> deleteProject(@RequestBody Project data) {
        try {
            this.projectService.delete(data);
            writeLog(LogConstant.OPER_DELETE,Result.CODE_SUCCESS,"项目："+data.getName());
            return new Result<>(Result.CODE_SUCCESS, "", data);
        } catch (Exception e) {
            LogOperator.err(loggerName, "deleteProject error", e);
            writeLog(LogConstant.OPER_DELETE,Result.CODE_FAILED,e.getMessage());
            return new Result<>(Result.CODE_FAILED, e.getMessage(), data);
        }
    }

    @ApiOperation(value = "查询项目列表", notes = "通过条件查询项目信息，返回List方式" +
            "支持模糊查询。")
    @ResponseBody
    //@PreAuthorize("hasAuthority('queryProcessRule')")
    @RequestMapping(value = "/queryProject", method = RequestMethod.GET)
    public List<Project> queryProject(
            @ApiParam(value = "当前页数， 以1开始。") @RequestParam(value = "page", required = false, defaultValue = "1") int page,
            @ApiParam(value = "当前页的内容长度。") @RequestParam(value = "size", required = false, defaultValue = "20") int size,
            @ApiParam(value = "排序方式：asc为升序，desc为降序。") @RequestParam(value = "order", required = false, defaultValue = "asc") String order,
            @ApiParam(value = "排序字段，与dto中声明的字段名称一致。") @RequestParam(value = "orderBy", required = false, defaultValue = "id") String orderBy,
            @ApiParam(value = "產品线Id") @RequestParam(value = "productLineId", required = false, defaultValue = "") Long productLineId,
            @ApiParam(value = "项目名称") @RequestParam(value = "projectName", required = false) String name) {
        return this.projectService.findByCondition(page, size, order, orderBy, productLineId, name);
    }

    @ApiOperation(value = "查询单个项目", notes = "通过ID查询项目详细信息,包含了组织列表")
    @ResponseBody

    @RequestMapping(value = "/queryProjectById/{id}", method = RequestMethod.GET)
    public Project queryProjectById(@ApiParam(value = "项目ID", required = true) @PathVariable("id") Long id) {
        return this.projectService.findById(id);
    }

 /*   @ApiOperation(value = "导入设备列表", notes = "向系统中导入设备列表")
    //@PreAuthorize("hasAuthority('createProject')")
    @ResponseBody
    @RequestMapping(value = "/importProjectList", method = RequestMethod.POST, consumes = "multipart/form-data")
    public Result<Integer> importProject(
            @ApiParam(value = "项目信息Excel表格。", required = true) @RequestParam("fileupload") MultipartFile file, HttpServletRequest request) {

        String[] title = {"设备编号", "设备名称", "设备地址", "设备类型", "设备型号", "设备厂家", "经度", "纬度", "项目名称", "产品线名称", "设备来源", "备注信息"};
        int headerNum = 1;
        int sheetIndex = 0;
        StringBuilder sb = new StringBuilder();
        if (file == null) {
            throw new CodeException(Result.CODE_FAILED, "文件不能为空！");
        }
        String fileName = file.getOriginalFilename();
        // //验证文件名是否合格
        if (!ExcelImportUtils.validateExcel(fileName)) {
            throw new CodeException(Result.CODE_FAILED, "文件必须是excel格式！");
        }
        long size = file.getSize();
        if (StringUtils.isEmpty(fileName) || size == 0) {
            throw new CodeException(Result.CODE_FAILED, "文件不能为空！");
        }

        // 创建导入Excel对象
        ImportExcel ei = null;
        List<Project> projectList = null;
        try {
            ei = new ImportExcel(file, headerNum, sheetIndex);

            StringBuilder errorSB = new StringBuilder();
            String errorStr = ei.validateHead(title);
            errorSB.append(errorStr);

            if (!StringUtils.isEmpty(errorSB.toString())) {
                throw new CodeException("1", "文件格式错误！");
            }

            // 获取传入Excel文件的数据，根据传入参数类型，自动转换为对象
            projectList = ei.getDataList(Project.class);
            //补充productlineId

            Map<String, Long> productLineMap = new HashMap<String, Long>();
            for (ProductLine productLine : productLineService.findAll()
                    ) {
                productLineMap.put(productLine.getName(), productLine.getId());
            }

            // 插入数据库
            for (Project project : projectList) {
                try {
                    //补充productlineId

                    project.setProductLineId(productLineMap.get(project.getProductLineName()));

                    projectService.create(project);
                } catch (Exception e) {
                    sb.append(e.getMessage() + "; ");
                }

            }

        } catch (Exception e) {
            LogOperator.err(loggerName, "import project error", e);
            return ResultUtil.error(Result.CODE_FAILED, e.getMessage());
        }
        if (sb.length() == 0) {
            return ResultUtil.success();
        } else {
            return ResultUtil.error(Result.CODE_FAILED, sb.toString());
        }
    }*/

    @ApiOperation(value = "导出项目列表", notes = "将系统中的项目信息导出到excel文件。")
    // @PreAuthorize("hasAuthority('queryProject')")
    @RequestMapping(value = {"/exportProjectList"}, method = RequestMethod.GET)
    public String exportProjectList(HttpServletRequest request, HttpServletResponse response) {
        String date = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        String fileName = "Project_" + date + ".xlsx";
        List<Project> projectList = this.projectService.findAll();

        try {
            ExportExcel exportExcel =new ExportExcel("项目信息", Project.class);
            exportExcel.setDatePattern("yyyy-MM-dd");
            exportExcel .setDataList(projectList).write(response, fileName).dispose();
            writeLog(LogConstant.OPER_EXPORT,Result.CODE_SUCCESS,fileName);
        } catch (IOException e) {
            LogOperator.err(loggerName, "export Project info failed!", e);
            writeLog(LogConstant.OPER_EXPORT,Result.CODE_FAILED,fileName+e.getMessage());
        }
        return null;
    }

    /**
     *
     * @param result
     * @param detail
     */
    private  void  writeLog(String op,String result, String detail){
        OperLog operLog =new OperLog();
        operLog.setOperateTime(new Date());
        operLog.setModule(LogConstantEx.MODULE_PROJECT);
        operLog.setCommand(op);
        operLog.setResult(result);
        operLog.setOperateUser(ServiceUtils.getLoginUser().getUsername());
        operLog.setDetail(detail);
        operLogService.writeLog(operLog);
    }
}
